const redis      = require("redis");
const config     = require('../crawler/config/config');
const logger     = require('./log');

const bluebird   = require('bluebird');
bluebird.promisifyAll(redis);

class jedis{

    constructor() {
        if(!jedis.single){
            this.jedisClient = null;
            this.init();
            jedis.single = this;
        }
        return jedis.single;
    }

    init(){
        try {
            this.jedisClient = redis.createClient(config.REDIS.port, config.REDIS.host, config.REDIS.options);
        } catch (e) {
            throw new Error(`Create redis client throw err. Message:${e.message} `);
        }
        logger.info(`Redis client init load successful.`);
        this.jedisClient.on("error", function(err) {
            logger.err(`Redis error: ${err}`);
        });
    }

    /**
     * Sadd value
     * @param key
     * @param value
     */
    async sadd(key,value){
        if(!key || key === ''){
            logger.err(`Redis sadd key must not empty`);
            return;
        }
        await this.jedisClient.saddAsync(key,value);
    }

    /**
     * 有序集合
     */
    async zadd(key,value){

    }

    /**
     * 获取集合中的集合 分段获取
     * @param key
     * @param cursor  游标
     * @param pattern 匹配模式
     * @param count 指定从数据集里返回多少元素，默认值为 10
     */
    async sscan(key,cursor,pattern,count){

    }

    /**
     * lpush value
     * @param key
     * @param value
     * @returns {Promise<void>}
     */
    async lpush(key,value){
        if(!key || key === ''){
            logger.err(`Redis lpush key must not empty`);
            return;
        }
        await this.jedisClient.lpushAsync(key,value);
    }

    /**
     * 移除并且返回列表的第一个元素
     * @param key
     * @returns {Promise<null|*>}
     */
    async lpop(key){
        if(!key || key === ''){
            logger.err(`Redis lpop key must not empty`);
            return null;
        }
        return await this.jedisClient.lpopAsync(key);
    }
    /**
     * 移除并且返回列表的最后一个元素
     * @param key
     * @returns {Promise<null|*>}
     */
    async rpop(key){
        if(!key || key === ''){
            logger.err(`Redis rpop key must not empty`);
            return null;
        }
        return await this.jedisClient.rpopAsync(key);
    }

    /**
     * 获取列表长度
     * @param key
     * @returns {Promise<void>}
     */
    async llen(key){
        if(!key || key === ''){
            logger.err(`Redis llen key must not empty`);
            return null;
        }
        return await this.jedisClient.llenAsync(key);
    }

    /**
     * 获取集合长度
     * @param key
     * @returns {*}
     */
    async scard(key){
       return this.jedisClient.scardAsync(key).then(function (number) {
            return number;
       });
    }

    /**
     * 随机返回集合中的一个元素并删除
     * @param key
     * @returns {*}
     */
    async spop(key){
        return this.jedisClient.spopAsync(key);
    }

    /**
     * 随机返回集合中的一个元素
     * @returns {Promise<void>}
     */
    async srandmember(key){
        return this.jedisClient.srandmemberAsync(key);
    }

    /**
     * 判断集合中是否存在此元素
     * @param key
     * @param value
     * @returns {Promise<any|Thenable<any>>}
     */
    async sismember(key,value){
        return this.jedisClient.sismemberAsync(key,value);
    }

    /**
     * 返回集合所有成员
     * @param key
     * @returns {*}
     */
    async smembers(key){
        return this.jedisClient.smembersAsync(key);
    }

    /**
     * Set value
     * @param key
     * @param value
     */
    async set(key,value){
        if(!key || key === ''){
            logger.err(`Redis set key must not empty`);
            return;
        }
        this.jedisClient.setAsync(key,value);
    }

    /**
     * Get value
     * @param key
     * @returns {Promise<*>}
     */
    async get(key) {
        return this.jedisClient.getAsync(key);
    }

    /**
     * Delete key.
     * @param key
     * @returns {Promise<*>}
     */
    async del(key){
        return this.jedisClient.delAsync(key);
    }

    /**
     * 删除set集合中的元素
     * @param val
     * @param key
     * @returns {Promise<void>}
     */
    async srem(key,val){
        return this.jedisClient.sremAsync(key,val);
    }

    /**
     * 删除list集合中的元素
     * @param val
     * @param key
     * @returns {Promise<void>}
     */
    async lrem(key,val){
        return this.jedisClient.lremAsync(key,val).then(function(value) {
            return value;
        });
    }

    /**
     * 移除列表的最后一个元素，并将该元素添加到另一个列表并返回。
     * @param sourceKey
     * @param targetKey
     * @returns {Promise<void>}
     */
    async rpoplpush(sourceKey,targetKey){
        return this.jedisClient.rpoplpushAsync(sourceKey,targetKey).then(function (value) {
            return value;
        })
    }
}

jedis.single = null;
module.exports = jedis;
